package pl.org.lutra.planner.log;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.DateFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;

public class LogFormatter extends Formatter {
    
    private DateFormat dateFormat = DateFormat.getDateTimeInstance();
    
    @Override
    public String format(LogRecord record) {
        StringBuffer sb = new StringBuffer();
        
        sb.append(dateFormat.format(new Date(record.getMillis()))).append(" ");
        sb.append("[").append(MyLevel.getLevel(record.getLevel())).append("] ");
        
        // sb.append("[").append(record.getThreadID()).append("] ");
        
        sb.append(record.getSourceClassName()).append(".").append(record.getSourceMethodName());
        
        Object[] parameters = record.getParameters();
        sb.append("(").append(parameters[0]).append(":").append(parameters[1]).append(")");
        
        String message = record.getMessage();
        if (message != null) {
            sb.append(" ").append(message);
        }
        
        if (record.getThrown() != null) {
            sb.append(System.getProperty("line.separator"));
            
            try {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                record.getThrown().printStackTrace(pw);
                pw.close();
                
                sb.append(sw.toString());
            } catch (Exception exception) {
            }
        } else {
            sb.append(System.getProperty("line.separator"));
        }
        
        return sb.toString();
    }
    
    private enum MyLevel {
        ERROR(Level.SEVERE, "ERROR"), WARNING(Level.WARNING, "WARN "), INFO(Level.INFO, "INFO "), DEBUG(
                Level.FINE, "DEBUG");
        
        private Level level;
        private String label;
        
        private MyLevel(Level level, String label) {
            this.level = level;
            this.label = label;
        }
        
        public static String getLevel(Level level) {
            for (MyLevel myLevel : values()) {
                if (myLevel.level.equals(level)) {
                    return myLevel.label;
                }
            }
            
            return level.getName();
        }
        
    }
    
}
